package com.learner.common.exception;

import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;


@EqualsAndHashCode(callSuper = true)
@Data
@Slf4j
public class RestException extends RuntimeException {


    /**
     * 异常代码
     */
    private Integer code = -2;
    /**
     * 异常提示
     */
    private String msg;
    /**
     * 异常错误
     */
    private String error;

    public RestException(Throwable e) {
        super(e.getMessage());
        setError(e);
    }

    public RestException(RestStatus status) {
        super(status.msg);
        setCode(status.code);
        setMsg(status.msg);
    }

    public RestException(RestStatus status, String msg) {
        super(msg);
        setCode(status.code);
        setMsg(msg);
    }

    public RestException(String msg) {
        super(msg);
        setMsg(msg);
    }

    public RestException(String msg, Throwable e) {
        super(msg);
        this.msg = msg;
        setError(e);
    }

    public RestException(Integer code, String msg) {
        super(msg);
        setCode(code);
        setMsg(msg);
    }

    public RestException(Integer code, String msg, String error) {
        super(msg);
        setCode(code);
        setMsg(msg);
        this.error = error;
    }

    public RestException(Integer code, String msg, Throwable e) {
        super(msg);
        setCode(code);
        setMsg(msg);
    }

    public RestException(Integer code, String... args) {
        //TODO
//        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public void setCode(Integer code) {
        if (code != null) {
            this.code = code;
        }
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }


    public Map<String, Object> toMap() {
        Map<String, Object> map = new HashMap<>(error != null ? 3 : 2);
        map.put("code", this.code);
        map.put("msg", this.msg);
        if (error != null) {
            map.put("error", this.error);
        }
        return map;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this.toMap());
    }

    public boolean isError() {
        return this.code.equals(RestStatus.ERROR.code);
    }

    public boolean isStatus(RestStatus status) {
        return status.code() == this.getCode();
    }

    public final static RestException UNAUTHORIZED = new RestException(-401, "非法操作，权限不足");

    public final static RestException NOT_FOUND = new RestException(-404, "内容不存在");

    public final static RestException FEIGN_HYSTRIX = new RestException(-1, "系统繁忙");

    private void setError(Throwable e) {
        log.error("系统异常", e);
        e.printStackTrace();
        this.code = RestStatus.ERROR.code;
        if (this.msg == null) {
            this.msg = RestStatus.ERROR.msg;
        }
        this.error = e.toString();
    }

}